import Foundation

extension Notification.Name {
    static let wallpaperHistoryChanged = Notification.Name("wallpaperHistoryChanged")
    static let setWallpaper = Notification.Name("setWallpaper")
    static let clearWallpaper = Notification.Name("clearWallpaper")
    static let togglePlayback = Notification.Name("togglePlayback")
    static let toggleMute = Notification.Name("toggleMute")
}

class WallpaperManager {
    static let shared = WallpaperManager()

    private let historyKey = "wallpaperHistory"
    private let lastSelectedKey = "lastSelectedWallpaperURL"
    private let lastDisplayModeKey = "lastDisplayMode"
    private let isMutedKey = "isMuted"
    private let isPlayingKey = "isPlaying"
    private let userDefaults = UserDefaults.standard
    
    private let wallpapersDirectory: URL = {
        let fileManager = FileManager.default
        let appSupportURL = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
        let directoryURL = appSupportURL.appendingPathComponent("livedesktop/Wallpapers")
        
        if !fileManager.fileExists(atPath: directoryURL.path) {
            try? fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)
        }
        
        return directoryURL
    }()


    private init() {}

    // MARK: - Public API

    func getHistory() -> [URL] {
        guard let urlStrings = userDefaults.stringArray(forKey: historyKey) else { return [] }
        return urlStrings.compactMap { URL(string: $0) }
    }

    func addWallpaper(url: URL) {
        let fileManager = FileManager.default
        let destinationURL = wallpapersDirectory.appendingPathComponent(url.lastPathComponent)
        
        do {
            if fileManager.fileExists(atPath: destinationURL.path) {
                // Optional: handle file name collision, e.g., by renaming
                // For now, we'll just overwrite.
                try fileManager.removeItem(at: destinationURL)
            }
            try fileManager.copyItem(at: url, to: destinationURL)
            
            var history = getHistory()
            guard !history.contains(destinationURL) else { return } // Avoid duplicates
            history.insert(destinationURL, at: 0)
            saveHistory(history)
            setLastSelectedWallpaper(url: destinationURL)
            NotificationCenter.default.post(name: .wallpaperHistoryChanged, object: nil)
        } catch {
            print("Error adding wallpaper: \(error)")
        }
    }

    func removeWallpaper(url: URL) {
        do {
            try FileManager.default.removeItem(at: url)
            
            var history = getHistory()
            history.removeAll { $0 == url }
            saveHistory(history)

            if getLastSelectedWallpaper() == url {
                clearLastSelectedWallpaper()
            }
            NotificationCenter.default.post(name: .wallpaperHistoryChanged, object: nil)
        } catch {
            print("Error removing wallpaper: \(error)")
        }
    }

    func setLastSelectedWallpaper(url: URL) {
        userDefaults.set(url.absoluteString, forKey: lastSelectedKey)
    }

    func getLastSelectedWallpaper() -> URL? {
        guard let urlString = userDefaults.string(forKey: lastSelectedKey) else { return nil }
        return URL(string: urlString)
    }
    
    func clearLastSelectedWallpaper() {
        userDefaults.removeObject(forKey: lastSelectedKey)
    }

    // MARK: - Private Helpers

    private func saveHistory(_ history: [URL]) {
        let urlStrings = history.map { $0.absoluteString }
        userDefaults.set(urlStrings, forKey: historyKey)
    }
    
    func setLastDisplayMode(_ mode: String) {
        userDefaults.set(mode, forKey: lastDisplayModeKey)
    }

    func getLastDisplayMode() -> String? {
        return userDefaults.string(forKey: lastDisplayModeKey)
    }
    
    // MARK: - Playback and Mute Control

    func setIsMuted(_ isMuted: Bool) {
        userDefaults.set(isMuted, forKey: isMutedKey)
    }

    func getIsMuted() -> Bool {
        return userDefaults.bool(forKey: isMutedKey)
    }

    func setIsPlaying(_ isPlaying: Bool) {
        userDefaults.set(isPlaying, forKey: isPlayingKey)
    }

    func getIsPlaying() -> Bool {
        // 默认是播放状态
        return userDefaults.object(forKey: isPlayingKey) as? Bool ?? true
    }
    
    // MARK: - Random Wallpaper Switching
    
    private var wallpaperSwitchTimer: Timer?
    private let isRandomSwitchingKey = "isRandomSwitching"
    private let wallpaperSwitchIntervalKey = "wallpaperSwitchInterval"

    func setIsRandomSwitching(_ isRandom: Bool) {
        userDefaults.set(isRandom, forKey: isRandomSwitchingKey)
        if isRandom {
            startRandomSwitching()
        } else {
            stopRandomSwitching()
        }
    }

    func getIsRandomSwitching() -> Bool {
        return userDefaults.bool(forKey: isRandomSwitchingKey)
    }

    func setWallpaperSwitchInterval(_ interval: TimeInterval) {
        userDefaults.set(interval, forKey: wallpaperSwitchIntervalKey)
        // If switching is already active, restart the timer with the new interval
        if getIsRandomSwitching() {
            startRandomSwitching()
        }
    }

    func getWallpaperSwitchInterval() -> TimeInterval {
        // Default to 1 hour (3600 seconds) if not set
        return userDefaults.object(forKey: wallpaperSwitchIntervalKey) as? TimeInterval ?? 3600
    }

    func startRandomSwitching() {
        stopRandomSwitching() // Ensure any existing timer is stopped before starting a new one
        let interval = getWallpaperSwitchInterval()
        guard interval > 0 else { return }

        wallpaperSwitchTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
            self?.switchToRandomWallpaper()
        }
    }

    func stopRandomSwitching() {
        wallpaperSwitchTimer?.invalidate()
        wallpaperSwitchTimer = nil
    }

    private func switchToRandomWallpaper() {
        let history = getHistory()
        guard !history.isEmpty else { return }

        let currentWallpaper = getLastSelectedWallpaper()
        var randomWallpaper = history.randomElement()

        // Ensure the new wallpaper is different from the current one, if possible
        if history.count > 1 {
            while randomWallpaper == currentWallpaper {
                randomWallpaper = history.randomElement()
            }
        }

        if let newWallpaper = randomWallpaper {
            setLastSelectedWallpaper(url: newWallpaper)
            // Post a notification to inform the UI to update the wallpaper
            NotificationCenter.default.post(name: .setWallpaper, object: nil, userInfo: ["url": newWallpaper])
        }
    }
}

